#include "DraggableRectItem.h"
#include <QPainter>
#include <QCursor>
#include <QGraphicsScene>
#include <QGraphicsItem>

DraggableRectItem::DraggableRectItem(const QRectF &rect, QGraphicsItem *parent) :
    QObject(nullptr),
    QGraphicsRectItem(rect, parent),
    m_isResizable(true),
    m_isDragging(false),
    m_isResizing(false),
    m_currentHandle(NoHandle),
    m_minimumSize(10, 10),
    m_handleSize(8)
{
    setFlag(QGraphicsItem::ItemIsMovable, true);
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
    setAcceptHoverEvents(true);
}

DraggableRectItem::DraggableRectItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent) :
    QObject(nullptr),
    QGraphicsRectItem(x, y, width, height, parent),
    m_isResizable(true),
    m_isDragging(false),
    m_isResizing(false),
    m_currentHandle(NoHandle),
    m_minimumSize(10, 10),
    m_handleSize(8)
{
    setFlag(QGraphicsItem::ItemIsMovable, true);
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
    setAcceptHoverEvents(true);
}

DraggableRectItem::DraggableRectItem(QGraphicsItem *parent) :
    QObject(nullptr),
    QGraphicsRectItem(parent),
    m_isResizable(true),
    m_isDragging(false),
    m_isResizing(false),
    m_currentHandle(NoHandle),
    m_minimumSize(10, 10),
    m_handleSize(8)
{
    setFlag(QGraphicsItem::ItemIsMovable, true);
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
    setAcceptHoverEvents(true);
}

void DraggableRectItem::setResizable(bool enabled)
{
    m_isResizable = enabled;
    update();
}

bool DraggableRectItem::isResizable() const
{
    return m_isResizable;
}

void DraggableRectItem::setMinimumSize(const QSizeF &size)
{
    m_minimumSize = size;
}

QSizeF DraggableRectItem::minimumSize() const
{
    return m_minimumSize;
}

void DraggableRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        // 检查是否在调整手柄上按下
        m_currentHandle = getHandleAt(event->pos());
        
        if (m_isResizable && m_currentHandle != NoHandle) {
            // 开始调整大小
            m_isResizing = true;
            m_startRect = rect();
            m_dragStartPos = event->pos();
        } else {
            // 开始拖动
            m_isDragging = true;
            m_itemStartPos = pos();
            m_dragStartPos = event->pos();
            QGraphicsRectItem::mousePressEvent(event);
        }
        
        event->accept();
    } else {
        QGraphicsRectItem::mousePressEvent(event);
    }
}

void DraggableRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_isResizing) {
        // 调整矩形大小
        resizeRect(event->pos());
        event->accept();
    } else if (m_isDragging) {
        // 拖动矩形
        QGraphicsRectItem::mouseMoveEvent(event);
        event->accept();
    } else {
        // 更新光标
        if (m_isResizable) {
            ResizeHandle handle = getHandleAt(event->pos());
            setCursorForHandle(handle);
        }
        QGraphicsRectItem::mouseMoveEvent(event);
    }
}

void DraggableRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_isDragging = false;
        m_isResizing = false;
        m_currentHandle = NoHandle;
        setCursor(Qt::ArrowCursor);
        
        // 通知场景更新
        if (scene()) {
            scene()->update();
        }
        
        QGraphicsRectItem::mouseReleaseEvent(event);
        event->accept();
    } else {
        QGraphicsRectItem::mouseReleaseEvent(event);
    }
}

void DraggableRectItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    if (m_isResizable) {
        ResizeHandle handle = getHandleAt(event->pos());
        setCursorForHandle(handle);
    }
    QGraphicsRectItem::hoverEnterEvent(event);
}

void DraggableRectItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    if (m_isResizable && !m_isResizing && !m_isDragging) {
        ResizeHandle handle = getHandleAt(event->pos());
        setCursorForHandle(handle);
    }
    QGraphicsRectItem::hoverMoveEvent(event);
}

void DraggableRectItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    if (!m_isResizing && !m_isDragging) {
        setCursor(Qt::ArrowCursor);
    }
    QGraphicsRectItem::hoverLeaveEvent(event);
}

void DraggableRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    // 绘制基础矩形
    QGraphicsRectItem::paint(painter, option, widget);
    
    // 如果启用了大小调整且矩形被选中，绘制调整手柄
    if (m_isResizable && isSelected()) {
        painter->save();
        painter->setBrush(Qt::white);
        painter->setPen(QPen(Qt::black, 1));
        
        // 绘制八个调整手柄
        qreal hs = m_handleSize / 2;
        QRectF rect = this->rect();
        
        // 左上角
        painter->drawRect(QRectF(rect.left() - hs, rect.top() - hs, m_handleSize, m_handleSize));
        // 顶部中间
        painter->drawRect(QRectF(rect.center().x() - hs, rect.top() - hs, m_handleSize, m_handleSize));
        // 右上角
        painter->drawRect(QRectF(rect.right() - hs, rect.top() - hs, m_handleSize, m_handleSize));
        // 右侧中间
        painter->drawRect(QRectF(rect.right() - hs, rect.center().y() - hs, m_handleSize, m_handleSize));
        // 右下角
        painter->drawRect(QRectF(rect.right() - hs, rect.bottom() - hs, m_handleSize, m_handleSize));
        // 底部中间
        painter->drawRect(QRectF(rect.center().x() - hs, rect.bottom() - hs, m_handleSize, m_handleSize));
        // 左下角
        painter->drawRect(QRectF(rect.left() - hs, rect.bottom() - hs, m_handleSize, m_handleSize));
        // 左侧中间
        painter->drawRect(QRectF(rect.left() - hs, rect.center().y() - hs, m_handleSize, m_handleSize));
        
        painter->restore();
    }
}

DraggableRectItem::ResizeHandle DraggableRectItem::getHandleAt(const QPointF &pos)
{
    if (!m_isResizable) {
        return NoHandle;
    }
    
    qreal hs = m_handleSize / 2;
    QRectF rect = this->rect();
    
    // 检查八个调整手柄区域
    if (QRectF(rect.left() - hs, rect.top() - hs, m_handleSize, m_handleSize).contains(pos))
        return LeftTop;
    if (QRectF(rect.center().x() - hs, rect.top() - hs, m_handleSize, m_handleSize).contains(pos))
        return Top;
    if (QRectF(rect.right() - hs, rect.top() - hs, m_handleSize, m_handleSize).contains(pos))
        return RightTop;
    if (QRectF(rect.right() - hs, rect.center().y() - hs, m_handleSize, m_handleSize).contains(pos))
        return Right;
    if (QRectF(rect.right() - hs, rect.bottom() - hs, m_handleSize, m_handleSize).contains(pos))
        return RightBottom;
    if (QRectF(rect.center().x() - hs, rect.bottom() - hs, m_handleSize, m_handleSize).contains(pos))
        return Bottom;
    if (QRectF(rect.left() - hs, rect.bottom() - hs, m_handleSize, m_handleSize).contains(pos))
        return LeftBottom;
    if (QRectF(rect.left() - hs, rect.center().y() - hs, m_handleSize, m_handleSize).contains(pos))
        return Left;
    
    return NoHandle;
}

void DraggableRectItem::setCursorForHandle(ResizeHandle handle)
{
    switch (handle) {
    case LeftTop:
    case RightBottom:
        setCursor(Qt::SizeFDiagCursor);
        break;
    case Top:
    case Bottom:
        setCursor(Qt::SizeVerCursor);
        break;
    case RightTop:
    case LeftBottom:
        setCursor(Qt::SizeBDiagCursor);
        break;
    case Left:
    case Right:
        setCursor(Qt::SizeHorCursor);
        break;
    case NoHandle:
    default:
        setCursor(Qt::ArrowCursor);
        break;
    }
}

void DraggableRectItem::resizeRect(const QPointF &pos)
{
    QRectF newRect = m_startRect;
    qreal dx = pos.x() - m_dragStartPos.x();
    qreal dy = pos.y() - m_dragStartPos.y();
    
    // 根据当前手柄类型调整矩形大小
    switch (m_currentHandle) {
    case LeftTop:
        newRect.setLeft(m_startRect.left() + dx);
        newRect.setTop(m_startRect.top() + dy);
        break;
    case Top:
        newRect.setTop(m_startRect.top() + dy);
        break;
    case RightTop:
        newRect.setRight(m_startRect.right() + dx);
        newRect.setTop(m_startRect.top() + dy);
        break;
    case Right:
        newRect.setRight(m_startRect.right() + dx);
        break;
    case RightBottom:
        newRect.setRight(m_startRect.right() + dx);
        newRect.setBottom(m_startRect.bottom() + dy);
        break;
    case Bottom:
        newRect.setBottom(m_startRect.bottom() + dy);
        break;
    case LeftBottom:
        newRect.setLeft(m_startRect.left() + dx);
        newRect.setBottom(m_startRect.bottom() + dy);
        break;
    case Left:
        newRect.setLeft(m_startRect.left() + dx);
        break;
    default:
        return;
    }
    
    // 确保矩形不小于最小尺寸
    if (newRect.width() < m_minimumSize.width()) {
        if (m_currentHandle == Left || m_currentHandle == LeftTop || m_currentHandle == LeftBottom) {
            newRect.setLeft(newRect.right() - m_minimumSize.width());
        } else if (m_currentHandle == Right || m_currentHandle == RightTop || m_currentHandle == RightBottom) {
            newRect.setRight(newRect.left() + m_minimumSize.width());
        }
    }
    
    if (newRect.height() < m_minimumSize.height()) {
        if (m_currentHandle == Top || m_currentHandle == LeftTop || m_currentHandle == RightTop) {
            newRect.setTop(newRect.bottom() - m_minimumSize.height());
        } else if (m_currentHandle == Bottom || m_currentHandle == LeftBottom || m_currentHandle == RightBottom) {
            newRect.setBottom(newRect.top() + m_minimumSize.height());
        }
    }
    
    // 设置新矩形
    setRect(newRect);
    
    // 通知场景更新
    if (scene()) {
        scene()->update();
    }
    
    // 发出大小变化信号
    emit sizeChanged();
}

QVariant DraggableRectItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == ItemPositionHasChanged) {
        // 位置发生变化时发出信号
        emit positionChanged();
    } else if (change == ItemTransformHasChanged) {
        // 变换（包括大小）发生变化时发出信号
        emit sizeChanged();
    }
    
    return QGraphicsRectItem::itemChange(change, value);
}
